package role

import (
	"gorm.io/gorm"
)

// Repository 角色数据访问层接口
type Repository interface {
	Create(role *Role) error
	GetByID(id uint) (*Role, error)
	GetByIDWithoutPermissions(id uint) (*Role, error)
	GetByName(name string) (*Role, error)
	GetByCode(code string) (*Role, error)
	Update(role *Role) error
	Delete(id uint) error
	List(req *QueryRequest) ([]*RoleWithPermissions, int64, error)
	UpdatePermissions(roleID uint, permissionIDs []uint) error
	GetRoleWithPermissions(id uint) (*RoleWithPermissions, error)
	GetAllRoles() ([]*Role, error)
}

// repository 角色数据访问层实现
type repository struct {
	db *gorm.DB
}

// NewRepository 创建角色数据访问层
func NewRepository(db *gorm.DB) Repository {
	return &repository{
		db: db,
	}
}

// Create 创建角色
func (r *repository) Create(role *Role) error {
	return r.db.Create(role).Error
}

// GetByID 根据ID获取角色（包含权限信息）
func (r *repository) GetByID(id uint) (*Role, error) {
	var role Role
	err := r.db.First(&role, id).Error
	if err != nil {
		return nil, err
	}
	return &role, nil
}

// GetByIDWithoutPermissions 根据ID获取角色（不包含权限信息，用于更新）
func (r *repository) GetByIDWithoutPermissions(id uint) (*Role, error) {
	var role Role
	err := r.db.First(&role, id).Error
	if err != nil {
		return nil, err
	}
	return &role, nil
}

// GetByName 根据名称获取角色
func (r *repository) GetByName(name string) (*Role, error) {
	var role Role
	err := r.db.Where("name = ?", name).First(&role).Error
	if err != nil {
		return nil, err
	}
	return &role, nil
}

// GetByCode 根据代码获取角色
func (r *repository) GetByCode(code string) (*Role, error) {
	var role Role
	err := r.db.Where("code = ?", code).First(&role).Error
	if err != nil {
		return nil, err
	}
	return &role, nil
}

// Update 更新角色
func (r *repository) Update(role *Role) error {
	return r.db.Save(role).Error
}

// Delete 删除角色
func (r *repository) Delete(id uint) error {
	return r.db.Delete(&Role{}, id).Error
}

// List 获取角色列表
func (r *repository) List(req *QueryRequest) ([]*RoleWithPermissions, int64, error) {
	var roles []*Role
	var total int64

	query := r.db.Model(&Role{})

	// 关键词搜索
	if req.Keyword != "" {
		query = query.Where("name LIKE ? OR display_name LIKE ? OR description LIKE ?",
			"%"+req.Keyword+"%", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}

	// 字段筛选
	if req.Name != "" {
		query = query.Where("name = ?", req.Name)
	}

	if req.DisplayName != "" {
		query = query.Where("display_name = ?", req.DisplayName)
	}

	if req.Status != nil {
		query = query.Where("status = ?", *req.Status)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (req.Page - 1) * req.PageSize
	if err := query.Offset(offset).Limit(req.PageSize).Order("id DESC").Find(&roles).Error; err != nil {
		return nil, 0, err
	}

	// 手动组装带权限的角色列表
	var result []*RoleWithPermissions
	for _, role := range roles {
		// 查询每个角色的权限
		var permissions []Permission
		err := r.db.Table("permissions").
			Joins("INNER JOIN role_permissions ON permissions.id = role_permissions.permission_id").
			Where("role_permissions.role_id = ? AND permissions.deleted_at IS NULL", role.ID).
			Find(&permissions).Error
		if err != nil {
			return nil, 0, err
		}

		// 组装结果
		roleWithPermissions := &RoleWithPermissions{
			ID:          role.ID,
			Name:        role.Name,
			Code:        role.Code,
			DisplayName: role.DisplayName,
			Description: role.Description,
			Status:      role.Status,
			CreatedAt:   role.CreatedAt,
			UpdatedAt:   role.UpdatedAt,
			Permissions: permissions,
		}
		result = append(result, roleWithPermissions)
	}

	return result, total, nil
}

// UpdatePermissions 更新角色权限
func (r *repository) UpdatePermissions(roleID uint, permissionIDs []uint) error {
	// 先清除现有权限关联
	if err := r.db.Exec("DELETE FROM role_permissions WHERE role_id = ?", roleID).Error; err != nil {
		return err
	}

	// 如果有新权限，则添加关联
	if len(permissionIDs) > 0 {
		for _, permissionID := range permissionIDs {
			if err := r.db.Exec("INSERT INTO role_permissions (role_id, permission_id) VALUES (?, ?)", roleID, permissionID).Error; err != nil {
				return err
			}
		}
	}

	return nil
}

// GetRoleWithPermissions 获取带权限信息的角色
func (r *repository) GetRoleWithPermissions(id uint) (*RoleWithPermissions, error) {
	// 1. 获取角色基本信息
	var role Role
	err := r.db.First(&role, id).Error
	if err != nil {
		return nil, err
	}

	// 2. 手动查询角色权限
	var permissions []Permission
	err = r.db.Table("permissions").
		Joins("INNER JOIN role_permissions ON permissions.id = role_permissions.permission_id").
		Where("role_permissions.role_id = ? AND permissions.deleted_at IS NULL", id).
		Find(&permissions).Error
	if err != nil {
		return nil, err
	}

	// 3. 组装结果
	result := &RoleWithPermissions{
		ID:          role.ID,
		Name:        role.Name,
		Code:        role.Code,
		DisplayName: role.DisplayName,
		Description: role.Description,
		Status:      role.Status,
		CreatedAt:   role.CreatedAt,
		UpdatedAt:   role.UpdatedAt,
		Permissions: permissions,
	}

	return result, nil
}

// GetAllRoles 获取所有角色（用于下拉选择等）
func (r *repository) GetAllRoles() ([]*Role, error) {
	var roles []*Role
	err := r.db.Where("status = ?", 1).Order("id ASC").Find(&roles).Error
	return roles, err
}
